package br.com.afi.util.hibernate.validator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * Classe que verifica se a String é um número.
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 */
public class NumberStrValidator implements ConstraintValidator<NumberStr, String>
{
	private int fractionDigits;
	private int integerDigits;
	private boolean exactMatch;

	public NumberStrValidator()
	{
		super();
	}

	public NumberStrValidator( int integerDigits, int fractionDigits, boolean exactMatch )
	{
		super();
		this.integerDigits = integerDigits;
		this.fractionDigits = fractionDigits;
		this.exactMatch = exactMatch;
	}

	@Override
	public void initialize( NumberStr parameters )
	{
		this.integerDigits = parameters.integerDigits();
		this.fractionDigits = parameters.fractionDigits();
		this.exactMatch = parameters.exactMatch();
	}

	@Override
	public boolean isValid( String value, ConstraintValidatorContext constraintContext )
	{
		if ( value == null )
		{
			return true;
		}
		if ( value.isEmpty() )
		{
			return true;
		}
		final String regex = "-?[0-9]*[,.]?[0-9]+";
		final Pattern pattern = Pattern.compile( regex );
		final Matcher matcher = pattern.matcher( value );

		boolean ok = matcher.matches();
		if ( ok )
		{
			if ( value.startsWith( "-" ) )
			{
				value = value.substring( 1, value.length() );
			}
			final boolean decimalNumber = value.contains( "," );
			if ( decimalNumber )
			{
				if ( fractionDigits != -1 )
				{
					final String aux[] = value.split( "," );
					final String integer = aux[0];
					final String decimal = aux[1];

					if ( exactMatch )
					{
						if ( decimal.length() != fractionDigits )
						{
							return false;
						}
						if ( integerDigits != 0 && integer.length() != integerDigits )
						{
							return false;
						}
					}
					else
					{
						if ( decimal.length() > fractionDigits )
						{
							return false;
						}
						if ( integerDigits != 0 && integer.length() > integerDigits )
						{
							return false;
						}
					}
				}
			}
			else
			{
				if ( integerDigits != -1 )
					if ( exactMatch )
					{
						if ( value.length() != integerDigits )
						{
							return false;
						}
					}
					else
					{
						if ( value.length() > integerDigits )
						{
							return false;
						}
					}
			}
		}
		return ok;
	}

}
